using System;
using System.Collections;
using System.Drawing;
using System.Globalization;
using System.Reflection;
using System.Runtime.Serialization;
using System.Security.Permissions;
using System.Windows.Forms;
using System.Collections.Generic;

namespace CartoGraphic.Model2
{
	[Serializable]
    public class Layers : ISerializable
    {
        //private ArrayList layerList;
        public Dictionary<string, Layer1> layerlist;

        private bool _isDirty;
        private const int MaxLayerCount = 10;

        public bool Dirty
        {
            get
            {
                if (_isDirty == false)
                {
                    foreach (KeyValuePair<string, Layer1> pair in layerlist)
                    {
                        if (pair.Value.Dirty)
                        {
                            _isDirty = true;
                            break;
                        }
                    }
                }
                return _isDirty;
            }
        }

        private const string entryCount = "LayerCount";
        private const string entryLayer = "LayerType";

        public Layers()
        {
            layerlist = new Dictionary<string, Layer1>();
        }

        public string ActiveLayerIndex
        {
            get
            {
                foreach (KeyValuePair<string, Layer1> pair in layerlist)
                {
                    if (pair.Value.IsActive)
                        return pair.Key;
                }
                return null;
            }
        }

        protected Layers(SerializationInfo info, StreamingContext context)
        {
            //layerlist = new Dictionary<string, Layer1>();

            //int n = info.GetInt32(entryCount);

            //for (int i = 0; i < n; i++)
            //{
            //    string typeName;
            //    typeName = info.GetString(
            //        String.Format(CultureInfo.InvariantCulture,
            //                      "{0}{1}",
            //                      entryLayer, i));

            //    object _layer;
            //    _layer = Assembly.GetExecutingAssembly().CreateInstance(typeName);
            //    ((Layer1)_layer).LoadFromStream(info, i);
            //    layerList.Add(_layer);
            //}
        }

        [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
        public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            //info.AddValue(entryCount, layerList.Count);

            //int i = 0;

            //foreach (Layer1 l in layerList)
            //{
            //    info.AddValue(
            //        String.Format(CultureInfo.InvariantCulture,
            //                      "{0}{1}",
            //                      entryLayer, i),
            //        l.GetType().FullName);

            //    l.SaveToStream(info, i);
            //    i++;
            //}
        }

        public void Draw(Graphics g)
        {
            
            for (int i = 0; i <MaxLayerCount; i++)
            {
                foreach (KeyValuePair<string, Layer1> pair in layerlist)
                {
                    if (pair.Value.IsVisible && pair.Value.Depth == i)
                    {
                        if(g!=null)
                            pair.Value.Draw(g);
                        break;
                    }
                        
                }
            }
        }


        public bool Clear()
        {
            bool result = (layerlist.Count > 0);
            foreach (KeyValuePair<string, Layer1> pair in layerlist)
                pair.Value.Graphics.Clear();
            layerlist.Clear();
            CreateNewLayer("Default");
            if (result)
                _isDirty = false;
            return result;
        }
        public int Count
        {
            get { return layerlist.Count; }
        }

        public Layer1 this[string index]
        {
            get
            {
                if (index == null)
                    return null;
                if (!layerlist.ContainsKey(index))
                    return null;
                return (Layer1)layerlist[index];
            }
        }

        public void Add(string name,Layer1 obj)
        {
            if(!layerlist.ContainsKey(name))
            layerlist.Add(name, obj);
        }

        public void CreateNewLayer(string theName)
        {
            foreach (KeyValuePair<string, Layer1> pair in layerlist)
                pair.Value.IsActive = false;
            Layer1 l = new Layer1();
            l.IsVisible = true;
            l.IsActive = true;
            l.LayerName = theName;
            l.Graphics = new GraphicsList();
            Add(theName,l);
        }

        public void InactivateAllLayers()
        {
            string activeIndex = ActiveLayerIndex;
            if (activeIndex == null)
                return;
            for (int i = 0; i < layerlist[activeIndex].Graphics.Count; i++)
                layerlist[activeIndex].Graphics[i].Selected = false;
            foreach (KeyValuePair<string, Layer1> pair in layerlist)
                pair.Value.IsActive = false;
        }

        public void MakeLayerInvisible(string p)
        {
            layerlist[p].IsVisible = false;
        }

        public void MakeLayerVisible(string p)
        {
            layerlist[p].IsVisible  = true;
        }

        public void SetActiveLayer(string p)
        {
            if (ActiveLayerIndex == p)
                return;
            if (ActiveLayerIndex == null)
            {
                layerlist[p].IsActive = true;
            }
            if (layerlist.ContainsKey(p))
            {
                if (layerlist[p].Graphics != null)
                    layerlist[p].Graphics.UnselectAll();
                layerlist[ActiveLayerIndex].IsActive = false;
                layerlist[p].IsActive = true;
                layerlist[p].IsVisible = true;
            }
        }

        public void RemoveLayer(string p)
        {
            if (ActiveLayerIndex == p)
            {
                MessageBox.Show("Cannot Remove the Active Layer");
                return;
            }
            if (layerlist.Count == 1)
            {
                MessageBox.Show("There is only one Layer in this drawing! You Cannot Remove the Only Layer!");
                return;
            }
            if (layerlist.ContainsKey(p))
            {
                layerlist[p].Graphics.Clear();
                layerlist.Remove(p);
            }
        }
    }
}